package com.meida.common.mybatis.query;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.meida.common.constants.CommonConstants;
import com.meida.common.mybatis.entity.EntityMap;
import com.meida.common.mybatis.model.UpdateModel;
import com.meida.common.utils.FlymeUtils;
import com.meida.common.utils.JsonUtils;
import com.meida.common.utils.ReflectionUtils;
import lombok.Data;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author zyf
 */
@Data
public class CriteriaUpdate<T> extends UpdateWrapper<T> implements Serializable {
    private EntityMap requestMap = new EntityMap();

    private String handlerName;

    /**
     * 表名
     */
    private String tableName;

    /**
     * 表别名
     */
    private String tableAlias;

    /**
     * 主键字段
     */
    private String idField;

    private Long[] ids;

    private Class<T> cls;

    private UpdateModel model;

    public EntityMap put(String key, Object value) {
        this.requestMap.put(key, value);
        return this.requestMap;
    }

    public CriteriaUpdate() {

    }

    public CriteriaUpdate(UpdateModel model, Class<T> cls) {
        this.handlerName = model.getHandlerName();
        this.model = model;
        this.cls = cls;
        this.idField = ReflectionUtils.getTableField(cls);
        String params = model.getParams();
        if (FlymeUtils.isNotEmpty(params)) {
            this.setRequestMap(JsonUtils.jsonToMap(params, false));
        }
        Long idValue = Optional.ofNullable(this.requestMap.getLong(idField)).orElse(FlymeUtils.getLong(model.getId()));
        if (FlymeUtils.isNotEmpty(idValue)) {
            this.requestMap.put(idField, idValue);
            //给主键赋值
            this.put(idField, idValue);
            this.eq(idField, idValue);
        }
    }

    public CriteriaUpdate(Map map, Class<T> cls) {
        this.cls = cls;
        this.handlerName = (String) map.getOrDefault(CommonConstants.HANDLER_NAME, "");
        this.setHandlerName(handlerName);
        this.tableName = ReflectionUtils.getTableName(cls);
        this.tableAlias = ReflectionUtils.getAlias(cls);
        this.idField = ReflectionUtils.getTableField(cls);
        Object params = map.get("params");
        EntityMap test;
        if (FlymeUtils.isNotEmpty(params)) {
            //TODO 便于接口文档测试
            test = JsonUtils.jsonToBean(params.toString(), EntityMap.class);
            this.requestMap.putAll(test);
        }else{
            this.requestMap.putAll(map);
        }
        Long idValue = Optional.ofNullable(this.requestMap.getLong(idField)).orElse(FlymeUtils.getLong(map.get("id")));
        if (FlymeUtils.isNotEmpty(idValue)) {
            this.ids = new Long[]{idValue};
            this.eq(true, idField, idValue);
            this.requestMap.put(idField, idValue);
        } else {
            Long[] idsValue = requestMap.getLongIds("ids");
            if (FlymeUtils.isNotEmpty(idsValue)) {
                this.ids = idsValue;
                if (idsValue.length > 1) {
                    this.in(true, idField, idsValue);
                    this.requestMap.put("ids", idsValue);

                } else {
                    this.ids[0] = idsValue[0];
                    this.requestMap.put(idField, idsValue[0]);
                    this.eq(true, idField, idsValue[0]);
                }
            }
        }
    }


    public List<Long> getArrayLong(String key) {
        return requestMap.getListLong(key);

    }

    public Long getLong(String key) {
        return requestMap.getLong(key);
    }

    public <T> T getParams(String key) {
        return (T) requestMap.get(key);
    }

    public <T> T getInt(String key,Integer def) {
        return (T) requestMap.getInt(key,def);
    }

    public <T> T getEntity(Class<T> cls) {
        T obj = JsonUtils.jsonToBean(JSONUtil.toJsonStr(requestMap), cls);
        return obj;
    }

    public Long[] getIds() {
        return ids;
    }
}
